package com.example.studentportrait.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.studentportrait.domain.ResponseResult;
import com.example.studentportrait.domain.dto.ListRoleDto;
import com.example.studentportrait.domain.dto.RoleDto;
import com.example.studentportrait.domain.dto.UpdateRoleDto;
import com.example.studentportrait.domain.entity.*;
import com.example.studentportrait.domain.vo.PageVo;
import com.example.studentportrait.domain.vo.RoleVo;
import com.example.studentportrait.enums.AppHttpCodeEnum;
import com.example.studentportrait.mapper.RoleMapper;
import com.example.studentportrait.service.PermissionService;
import com.example.studentportrait.service.RolePermissionService;
import com.example.studentportrait.service.RoleService;
import com.example.studentportrait.utils.BeanCopyUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 角色信息表(Role)表服务实现类
 *
 * @author makejava
 * @since 2023-10-17 21:18:32
 */
@Service("roleService")
public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements RoleService {

    @Autowired
    PermissionService permissionService;

    @Autowired
    RolePermissionService rolePermissionService;

    // 查询角色列表
    @Override
    public ResponseResult roleList(Integer pageNum, Integer pageSize, ListRoleDto listRoleDto) {
        // 查询基础角色信息
        LambdaQueryWrapper<Role> lqw = new LambdaQueryWrapper<>();
        lqw.eq(Role::getIsDelete, 0);
        lqw.eq(StringUtils.hasText(listRoleDto.getRoleName()), Role::getRoleName, listRoleDto.getRoleName());
        lqw.eq(listRoleDto.getStatus() != null, Role::getStatus, listRoleDto.getStatus());

        // 分页查询
        Page<Role> page = new Page<>(pageNum, pageSize);
        page(page, lqw);

        // 获取查询结果
        List<Role> roleList = page.getRecords();
        if (roleList.isEmpty()) {
            return ResponseResult.okResult(new PageVo(Collections.emptyList(), 0L));
        }

        List<RoleVo> roleVos;

        if (listRoleDto.getPermissionType() != null) {
            // 如果权限类型不为空，根据权限类型查询权限表
            LambdaQueryWrapper<Permission> permissionQuery = new LambdaQueryWrapper<>();
            permissionQuery.eq(Permission::getPermissionType, listRoleDto.getPermissionType());
            List<Permission> permissions = permissionService.list(permissionQuery);

            if (permissions.isEmpty()) {
                return ResponseResult.okResult(new PageVo(Collections.emptyList(), 0L));
            }

            // 获取权限 ID 列表
            List<Long> permissionIds = permissions.stream()
                    .map(Permission::getId)
                    .collect(Collectors.toList());

            // 根据权限 ID 查询角色权限表，获取符合条件的角色 ID
            LambdaQueryWrapper<RolePermission> rolePermissionQuery = new LambdaQueryWrapper<>();
            rolePermissionQuery.in(RolePermission::getPermissionId, permissionIds);
            List<RolePermission> rolePermissions = rolePermissionService.list(rolePermissionQuery);

            if (rolePermissions.isEmpty()) {
                return ResponseResult.okResult(new PageVo(Collections.emptyList(), 0L));
            }

            // 获取符合条件的角色 ID
            Set<Long> filteredRoleIds = rolePermissions.stream()
                    .map(RolePermission::getRoleId)
                    .collect(Collectors.toSet());

            // 过滤出符合条件的角色
            List<Role> filteredRoles = roleList.stream()
                    .filter(role -> filteredRoleIds.contains(role.getId()))
                    .collect(Collectors.toList());

            // 构造 RoleVo 并设置权限类型
            roleVos = filteredRoles.stream()
                    .map(role -> {
                        RoleVo roleVo = new RoleVo();
                        BeanUtils.copyProperties(role, roleVo);

                        // 设置权限类型
                        rolePermissions.stream()
                                .filter(rp -> rp.getRoleId().equals(role.getId()))
                                .findFirst()
                                .ifPresent(rp -> {
                                    Permission permission = permissions.stream()
                                            .filter(p -> p.getId().equals(rp.getPermissionId()))
                                            .findFirst()
                                            .orElse(null);
                                    if (permission != null) {
                                        roleVo.setPermissionType(permission.getPermissionType());
                                    }
                                });

                        return roleVo;
                    })
                    .collect(Collectors.toList());
        } else {
            // 如果权限类型为空，根据角色 ID 查询角色权限表
            List<Long> roleIds = roleList.stream()
                    .map(Role::getId)
                    .collect(Collectors.toList());

            LambdaQueryWrapper<RolePermission> rolePermissionQuery = new LambdaQueryWrapper<>();
            rolePermissionQuery.in(RolePermission::getRoleId, roleIds);
            List<RolePermission> rolePermissions = rolePermissionService.list(rolePermissionQuery);

            if (rolePermissions.isEmpty()) {
                return ResponseResult.okResult(new PageVo(Collections.emptyList(), 0L));
            }

            // 获取权限 ID 列表
            List<Long> permissionIds = rolePermissions.stream()
                    .map(RolePermission::getPermissionId)
                    .collect(Collectors.toList());

            // 查询权限表获取所有权限
            List<Permission> permissions = permissionService.listByIds(permissionIds);

            // 构造 RoleVo 并设置权限类型
            roleVos = roleList.stream()
                    .map(role -> {
                        RoleVo roleVo = new RoleVo();
                        BeanUtils.copyProperties(role, roleVo);

                        // 设置权限类型
                        rolePermissions.stream()
                                .filter(rp -> rp.getRoleId().equals(role.getId()))
                                .findFirst()
                                .ifPresent(rp -> {
                                    Permission permission = permissions.stream()
                                            .filter(p -> p.getId().equals(rp.getPermissionId()))
                                            .findFirst()
                                            .orElse(null);
                                    if (permission != null) {
                                        roleVo.setPermissionType(permission.getPermissionType());
                                    }
                                });

                        return roleVo;
                    })
                    .collect(Collectors.toList());
        }

        // 更新总条数为筛选后的记录数
        long filteredTotal = roleVos.size();
        // 构造返回结果
        PageVo pageVo = new PageVo(roleVos, filteredTotal);
        return ResponseResult.okResult(pageVo);
    }

    //新增角色
    @Transactional
    @Override
    public ResponseResult addRole(RoleDto roleDto) {
        // 1. 将角色信息保存到角色表
        Role role = BeanCopyUtils.copyBean(roleDto, Role.class);
        save(role); // 保存角色到数据库

        // 2. 根据 roleDto 中的 permissionType 查询权限表，获取权限 ID
        LambdaQueryWrapper<Permission> permissionQuery = new LambdaQueryWrapper<>();
        permissionQuery.eq(Permission::getPermissionType, roleDto.getPermissionType());
        Permission permission = permissionService.getOne(permissionQuery);

        if (permission == null) {
            // 如果未找到对应的权限，返回错误信息
            return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST, "权限类型不存在");
        }

        // 3. 根据 roleDto 中的 roleName 查询刚新增的角色 ID
        LambdaQueryWrapper<Role> roleQuery = new LambdaQueryWrapper<>();
        roleQuery.eq(Role::getRoleName, roleDto.getRoleName());
        roleQuery.last("LIMIT 1"); // 确保只查询一条记录
        Role savedRole = getOne(roleQuery);

        if (savedRole == null) {
            // 如果未找到新增的角色，返回错误信息
            return ResponseResult.errorResult(AppHttpCodeEnum.CONTENT_NOT_NULL, "角色保存失败");
        }

        // 4. 将角色 ID 和权限 ID 插入到角色权限表
        RolePermission rolePermission = new RolePermission();
        rolePermission.setRoleId(savedRole.getId());
        rolePermission.setPermissionId(permission.getId());
        rolePermissionService.save(rolePermission);

        // 5. 返回成功结果
        return ResponseResult.okResult("新增角色成功");
    }

    //编辑角色
    @Override
    public ResponseResult updateRole(UpdateRoleDto updateRoleDto) {
        // 1. 更新角色表
        Role role = BeanCopyUtils.copyBean(updateRoleDto, Role.class);
        UpdateWrapper<Role> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("id", updateRoleDto.getId()) // 匹配角色 ID
                .set(StringUtils.hasText(updateRoleDto.getRoleName()), "role_name", updateRoleDto.getRoleName()) // 更新角色名称
                .set(updateRoleDto.getStatus() != null, "status", updateRoleDto.getStatus()); // 更新状态

        boolean roleUpdated = update(updateWrapper);
        if (!roleUpdated) {
            return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST, "角色更新失败或不存在");
        }

        // 2. 查询权限表，获取权限 ID
        LambdaQueryWrapper<Permission> permissionQuery = new LambdaQueryWrapper<>();
        permissionQuery.eq(Permission::getPermissionType, updateRoleDto.getPermissionType());
        Permission permission = permissionService.getOne(permissionQuery);

        if (permission == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST, "权限类型不存在");
        }

        // 3. 更新角色权限表
        Long roleId = updateRoleDto.getId();
        Long permissionId = permission.getId();

        // 检查是否已有记录
        LambdaQueryWrapper<RolePermission> rolePermissionQuery = new LambdaQueryWrapper<>();
        rolePermissionQuery.eq(RolePermission::getRoleId, roleId);

        RolePermission rolePermission = rolePermissionService.getOne(rolePermissionQuery);
        if (rolePermission != null) {
            // 如果记录存在，更新权限 ID
            UpdateWrapper<RolePermission> rolePermissionWrapper = new UpdateWrapper<>();
            rolePermissionWrapper.eq("role_id", roleId)
                    .set("permission_id", permissionId);

            boolean rolePermissionUpdated = rolePermissionService.update(rolePermissionWrapper);
            if (!rolePermissionUpdated) {
                return ResponseResult.errorResult(AppHttpCodeEnum.SYSTEM_ERROR, "角色权限更新失败");
            }

            return ResponseResult.okResult("角色更新成功");
        } else {
            // 如果记录不存在，插入新记录
            RolePermission newRolePermission = new RolePermission();
            newRolePermission.setRoleId(roleId);
            newRolePermission.setPermissionId(permissionId);
            boolean rolePermissionAdded = rolePermissionService.save(newRolePermission);
            if (!rolePermissionAdded) {
                return ResponseResult.errorResult(AppHttpCodeEnum.SYSTEM_ERROR, "角色权限新增失败");
            }
        }

        return ResponseResult.okResult("角色更新成功");
    }

    //删除角色
    @Override
    public ResponseResult deleteRole(Long id) {
        // 1. 删除角色权限表中的对应记录
        LambdaQueryWrapper<RolePermission> rolePermissionQuery = new LambdaQueryWrapper<>();
        rolePermissionQuery.eq(RolePermission::getRoleId, id);

        boolean rolePermissionDeleted = rolePermissionService.remove(rolePermissionQuery);
        if (!rolePermissionDeleted) {
            return ResponseResult.errorResult(AppHttpCodeEnum.SYSTEM_ERROR, "删除角色权限失败");
        }

        // 2. 删除角色表中的对应记录
        boolean roleDeleted = removeById(id);
        if (!roleDeleted) {
            return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST, "删除角色失败或角色不存在");
        }

        // 3. 返回成功结果
        return ResponseResult.okResult("角色删除成功");
    }

    //获取可选的权限
    @Override
    public ResponseResult getPermissionList() {
        // 1. 查询权限表中所有未删除的权限记录
        LambdaQueryWrapper<Permission> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Permission::getIsDelete, 0); // 确保权限未被删除

        List<Permission> permissionList = permissionService.list(queryWrapper);

        // 2. 返回结果
        return ResponseResult.okResult(permissionList);
    }


}

